package com.block.account.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.block.account.enums.AccountTypeEnum;
import com.block.account.enums.ActionTypeEnum;
import com.block.account.factory.AccountTypeFactory;
import com.block.account.model.dto.ChangeAmountDTO;
import com.block.account.model.result.ChangeAmountResult;
import com.block.account.service.IAccountHandleService;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.service.LogFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;

@Service
public class AccountHandleService implements IAccountHandleService {

    private Logger log = LogFactory.getAccountLog();

    @Autowired
    NotifyExceptionService notifyExceptionService;

    /**
     * 入账
     * 消耗
     * 生成账单（直接入账）
     * 调账（子账户信息）
     */
    @Override
    @Transactional
    public boolean changeAmountHandle(ChangeAmountDTO changeAmountDTO){

        log.info("【执行入账操作】【changeAmountDTO】{}" , JSON.toJSONString(changeAmountDTO));

        AccountTypeEnum accountTypeEnum = changeAmountDTO.getAccountTypeEnum();
        ChangeAmountResult changeAmountResult = AccountTypeFactory.getService(accountTypeEnum.getValue()).changeAmount(changeAmountDTO);
        log.info("【执行入账操作】执行入账完成【changeAmountResult】{}【changeAmountDTO】{}" , JSON.toJSONString(changeAmountResult), JSON.toJSONString(changeAmountDTO));
        // 进行主账户记录的更新
        if (!changeAmountResult.isSuccess()){
            return false;
        }

        // 充值/退款 操作，需要同步更新总账户的信息
        if (ActionTypeEnum.updateMainAction(changeAmountDTO.getActionTypeEnum().getValue())){
            // 更新主账户的信息
            ChangeAmountDTO changeMainDto = new ChangeAmountDTO();
            changeMainDto.setAccountId(changeAmountDTO.getMainAccountId());
            changeMainDto.setChangeAmount(changeAmountDTO.getChangeAmount());
            changeMainDto.setActionTypeEnum(changeAmountDTO.getActionTypeEnum());
            changeMainDto.setAccountTypeEnum(AccountTypeEnum.ACCOUNT);
            changeMainDto.setBillDateInfo(changeAmountDTO.getBillDateInfo());
            changeMainDto.setDataInfo(changeAmountDTO.getDataInfo());
            // 设置备注信息
            String remarkInfo = StrUtil.format("{} [{}({})] {} ", changeAmountDTO.getAccountTypeEnum().getName(), changeAmountDTO.getAccountName(), changeAmountDTO.getAccountId(), changeAmountDTO.getActionTypeEnum().getName());
            changeMainDto.setRemarkInfo(remarkInfo);
            changeMainDto.setOperatorId(changeAmountDTO.getOperatorId());
            changeMainDto.setOperatorName(changeAmountDTO.getOperatorName());

            ChangeAmountResult changeMainResult =
                    AccountTypeFactory.getService(AccountTypeEnum.ACCOUNT.getValue())
                    .changeAmount(changeMainDto);

            log.info("【执行入账操作】执行主账户入账完成【changeMainResult】{}【changeMainDto】{}" , JSON.toJSONString(changeMainResult), JSON.toJSONString(changeMainDto));
            if (!changeMainResult.isSuccess()){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        }

        // 调账操作
        // 只有另外一个账户不为空的时候，才进行操作
        if (StrUtil.equals(changeAmountDTO.getActionTypeEnum().getValue(), ActionTypeEnum.TZ.getValue()) &&
                ObjectUtil.isNotEmpty(changeAmountDTO.getMainAccountId())){

            AccountTypeEnum accountTypeEnum1 = changeAmountDTO.getAccountTypeEnum();

            ChangeAmountDTO changeAdjustDto = new ChangeAmountDTO();
            BigDecimal changeAmount = NumberUtil.sub(BigDecimal.ZERO, changeAmountDTO.getChangeAmount());

            changeAdjustDto.setAccountId(changeAmountDTO.getMainAccountId());
            changeAdjustDto.setChangeAmount(changeAmount);
            changeAdjustDto.setActionTypeEnum(changeAmountDTO.getActionTypeEnum());
            changeAdjustDto.setAccountTypeEnum(accountTypeEnum1);
            changeAdjustDto.setBillDateInfo(changeAmountDTO.getBillDateInfo());
            changeAdjustDto.setDataInfo(changeAmountDTO.getDataInfo());
            changeAdjustDto.setRemarkInfo(changeAmountDTO.getRemarkInfo());
            changeAdjustDto.setOperatorId(changeAmountDTO.getOperatorId());
            changeAdjustDto.setOperatorName(changeAmountDTO.getOperatorName());

            ChangeAmountResult toChangeResult =
                    AccountTypeFactory.getService(accountTypeEnum1.getValue())
                            .changeAmount(changeAdjustDto);

            log.info("【执行入账操作】执行主账户调账完成【toChangeResult】{}【changeAdjustDto】{}" , JSON.toJSONString(toChangeResult), JSON.toJSONString(changeAdjustDto));
            if (!toChangeResult.isSuccess()){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        }

        // 消息通知
        if (changeAmountResult.isNoticeFlag()){
            notifyExceptionService.notifyWechatException("ACCOUNT_NOTICE", "账户消息通知", changeAmountResult.getNoticeContent(), null);
        }

        // 是否进行调账的操作
        return true;
    }


}
